/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.fzhucc.modules.Msg.service;

import com.fzhucc.exception.BadRequestException;
import com.fzhucc.modules.Msg.domain.Msg;
import com.fzhucc.modules.Msg.domain.dto.*;
import com.fzhucc.modules.activity.domain.Activity;
import com.fzhucc.modules.activity.repository.ActivityRepository;
import com.fzhucc.modules.elegant.domain.Elegant;
import com.fzhucc.modules.elegant.repository.ElegantRepository;
import com.fzhucc.modules.lesson.domain.Lesson;
import com.fzhucc.modules.lesson.repository.LessonRepository;
import com.fzhucc.modules.live.domain.Live;
import com.fzhucc.modules.sciEnterprise.domain.SciEnterprise;
import com.fzhucc.modules.sciEnterprise.domain.dto.AuditEnterpriseDto;
import com.fzhucc.modules.sciPersonnelInfo.domain.SciPersonnelInfo;
import com.fzhucc.modules.sciPersonnelInfo.repository.SciPersonnelInfoRepository;
import com.fzhucc.modules.sciStudio.domain.SciStudio;
import com.fzhucc.modules.sciStudio.repository.SciStudioRepository;
import com.fzhucc.modules.sciTechnologyDemand.domain.SciTechnologyDemand;
import com.fzhucc.modules.sciTechnologyDemand.repository.SciTechnologyDemandRepository;
import com.fzhucc.modules.system.domain.UserSmall;
import com.fzhucc.modules.system.repository.UserSmallRepository;
import com.fzhucc.modules.ts.domain.TsTeam;
import com.fzhucc.modules.ts.repository.TsTeamRepository;
import com.fzhucc.utils.*;
import lombok.RequiredArgsConstructor;
import com.fzhucc.modules.Msg.repository.MsgRepository;
import com.fzhucc.modules.Msg.service.mapstruct.MsgMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
 * @author yyg
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2024-06-13
 **/
@Service
@RequiredArgsConstructor
public class MsgService {

    private final MsgRepository msgRepository;

    private final ActivityRepository activityRepository;

    private final SciPersonnelInfoRepository sciPersonnelInfoRepository;

    private final SciTechnologyDemandRepository sciTechnologyDemandRepository;

    private final LessonRepository lessonRepository;

    private final ElegantRepository elegantRepository;

    private final TsTeamRepository tsTeamRepository;

    private final SciStudioRepository sciStudioRepository;
    private final MsgMapper msgMapper;

    private final UserSmallRepository userSmallRepository;

    public static final String HD = "活动";
    public static final String FC = "风采";
    public static final String XT = "学堂";
    public static final String XQ = "需求";
    public static final String LM = "劳模工匠";
    public static final String GZS = "工作室";
    public static final String FWD = "服务队";

    public Map<String, Object> queryAll(MsgQueryCriteria criteria, Pageable pageable) {
        criteria.setIsDelete(0);
        Page<Msg> page = msgRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Page<MsgDto> map = page.map(msgMapper::toDto);
        List<MsgDto> list = map.getContent();
        if (list != null && list.size() > 0) {
            for (MsgDto dto : list) {
                String type = dto.getType();
                Integer glId = dto.getGlId();
                if (type.contains(HD)) {
                    Optional<Activity> res = activityRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getTitle());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(FC)) {
                    Optional<Elegant> res = elegantRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getTitle());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(XT)) {
                    Optional<Lesson> res = lessonRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(XQ)) {
                    Optional<SciTechnologyDemand> res = sciTechnologyDemandRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getSlogan());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(LM)) {
                    Optional<SciPersonnelInfo> res = sciPersonnelInfoRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getZqxname());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(GZS)) {
                    Optional<SciStudio> res = sciStudioRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(FWD)) {
                    Optional<TsTeam> res = tsTeamRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getInfoName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                }
                Optional<UserSmall> res = userSmallRepository.findById(dto.getUserId());
                if (res.isPresent()) {
                    dto.setUserSmall(res.get());
                }
            }
        }
        return PageUtil.toPage(map);
    }


    public Map<String, Object> getByGlIdType(MsgQueryCriteria criteria, Pageable pageable) {
        criteria.setIsDelete(0);
        criteria.setAuditStatus("审核通过");
        Page<Msg> page = msgRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Page<MsgDto> map = page.map(msgMapper::toDto);
        List<MsgDto> list = map.getContent();
        if (list != null && list.size() > 0) {
            for (MsgDto dto : list) {
                String type = dto.getType();
                Integer glId = dto.getGlId();
                if (type.contains(HD)) {
                    Optional<Activity> res = activityRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getTitle());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(FC)) {
                    Optional<Elegant> res = elegantRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getTitle());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(XT)) {
                    Optional<Lesson> res = lessonRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(XQ)) {
                    Optional<SciTechnologyDemand> res = sciTechnologyDemandRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getSlogan());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(LM)) {
                    Optional<SciPersonnelInfo> res = sciPersonnelInfoRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getZqxname());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(GZS)) {
                    Optional<SciStudio> res = sciStudioRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(FWD)) {
                    Optional<TsTeam> res = tsTeamRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getInfoName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                }

                Optional<UserSmall> res = userSmallRepository.findById(dto.getUserId());
                if (res.isPresent()) {
                    dto.setUserSmall(res.get());
                }
            }
        }
        return PageUtil.toPage(map);
    }

    public Map<String, Object> my(MsgQueryCriteria criteria, Pageable pageable) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("未找到登录用户");
        }
        criteria.setUserId(userId);
        criteria.setIsDelete(0);
        Page<Msg> page = msgRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Page<MsgDto> map = page.map(msgMapper::toDto);
        List<MsgDto> list = map.getContent();
        if (list != null && list.size() > 0) {
            for (MsgDto dto : list) {
                String type = dto.getType();
                Integer glId = dto.getGlId();
                if (type.contains(HD)) {
                    Optional<Activity> res = activityRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getTitle());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(FC)) {
                    Optional<Elegant> res = elegantRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getTitle());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(XT)) {
                    Optional<Lesson> res = lessonRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(XQ)) {
                    Optional<SciTechnologyDemand> res = sciTechnologyDemandRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getSlogan());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(LM)) {
                    Optional<SciPersonnelInfo> res = sciPersonnelInfoRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getZqxname());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(GZS)) {
                    Optional<SciStudio> res = sciStudioRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                } else if (type.contains(FWD)) {
                    Optional<TsTeam> res = tsTeamRepository.findById(glId);
                    if (res.isPresent()) {
                        SmallGlDto smallGlDto = new SmallGlDto();
                        smallGlDto.setGlId(glId);
                        smallGlDto.setName(res.get().getInfoName());
                        dto.setSmallGlDto(smallGlDto);
                    }
                }
                Optional<UserSmall> res = userSmallRepository.findById(dto.getUserId());
                if (res.isPresent()) {
                    dto.setUserSmall(res.get());
                }
            }
        }
        return PageUtil.toPage(map);
    }

    public List<MsgDto> queryAll(MsgQueryCriteria criteria) {
        criteria.setIsDelete(0);
        return msgMapper.toDto(msgRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Transactional
    public MsgDto findById(Integer id) {
        Msg msg = msgRepository.findById(id).orElseGet(Msg::new);
        ValidationUtil.isNull(msg.getId(), "Msg", "id", id);
        MsgDto dto = msgMapper.toDto(msg);
        String type = dto.getType();
        Integer glId = dto.getGlId();
        if (type.contains(HD)) {
            Optional<Activity> res = activityRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getTitle());
                dto.setSmallGlDto(smallGlDto);
            }
        } else if (type.contains(FC)) {
            Optional<Elegant> res = elegantRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getTitle());
                dto.setSmallGlDto(smallGlDto);
            }
        } else if (type.contains(XT)) {
            Optional<Lesson> res = lessonRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getName());
                dto.setSmallGlDto(smallGlDto);
            }
        } else if (type.contains(XQ)) {
            Optional<SciTechnologyDemand> res = sciTechnologyDemandRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getSlogan());
                dto.setSmallGlDto(smallGlDto);
            }
        } else if (type.contains(LM)) {
            Optional<SciPersonnelInfo> res = sciPersonnelInfoRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getZqxname());
                dto.setSmallGlDto(smallGlDto);
            }
        } else if (type.contains(GZS)) {
            Optional<SciStudio> res = sciStudioRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getName());
                dto.setSmallGlDto(smallGlDto);
            }
        } else if (type.contains(FWD)) {
            Optional<TsTeam> res = tsTeamRepository.findById(glId);
            if (res.isPresent()) {
                SmallGlDto smallGlDto = new SmallGlDto();
                smallGlDto.setGlId(glId);
                smallGlDto.setName(res.get().getInfoName());
                dto.setSmallGlDto(smallGlDto);
            }
        }
        Optional<UserSmall> res = userSmallRepository.findById(dto.getUserId());
        if (res.isPresent()) {
            dto.setUserSmall(res.get());
        }
        return dto;
    }

    @Transactional(rollbackFor = Exception.class)
    public MsgDto create(Msg resources) {
        return msgMapper.toDto(msgRepository.save(resources));
    }

    @Transactional(rollbackFor = Exception.class)
    public MsgDto saveMsg(SaveMsgDto dto) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("请先登录后进行操作");
        }
        String context = dto.getContext();
        if (context == null) {
            throw new BadRequestException("请输入留言内容");
        }
        String type = dto.getType();
        if (type == null) {
            throw new BadRequestException("请选择留言类型");
        }
        Integer glId = dto.getGlId();
        if (glId == null) {
            throw new BadRequestException("请选择关联id");
        }
        if (type.contains(HD)) {
            Optional<Activity> res = activityRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该活动");
            }
        } else if (type.contains(FC)) {
            Optional<Elegant> res = elegantRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该劳模风采");
            }
        } else if (type.contains(XT)) {
            Optional<Lesson> res = lessonRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该工匠学堂");
            }
        } else if (type.contains(XQ)) {
            Optional<SciTechnologyDemand> res = sciTechnologyDemandRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该企业需求");
            }
        } else if (type.contains(LM)) {
            Optional<SciPersonnelInfo> res = sciPersonnelInfoRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该劳模工匠");
            }
        } else if (type.contains(GZS)) {
            Optional<SciStudio> res = sciStudioRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该工作室");
            }
        } else if (type.contains(FWD)) {
            Optional<TsTeam> res = tsTeamRepository.findById(glId);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该技术服务队");
            }
        } else {
            throw new BadRequestException("请选择符合的留言类型");
        }
        Msg resources = new Msg();
        resources.setUserId(userId);
        resources.setContext(context);
        resources.setGlId(glId);
        resources.setType(type);
        resources.setAuditStatus("待审核");
        resources.setIsDelete(0);
        return msgMapper.toDto(msgRepository.save(resources));
    }

    @Transactional(rollbackFor = Exception.class)
    public void audit(AuditMsgDto dto) {
        Optional<Msg> res = msgRepository.findById(dto.getId());
        if (!res.isPresent()) {
            throw new BadRequestException("未找到留言id");
        }
        String cAuditStatus = dto.getAuditStatus();
        if (cAuditStatus == null || cAuditStatus.equals("")) {
            throw new BadRequestException("缺少审核状态");
        }
        if (!cAuditStatus.contains("审核")) {
            throw new BadRequestException("不允许的审核状态");
        }
        Msg msg = res.get();
        msg.setAuditStatus(cAuditStatus);
        msgRepository.save(msg);
    }

    @Transactional(rollbackFor = Exception.class)
    public void auditPass(AuditMsgPassDto dto) {
        Integer[] ids = dto.getIds();
        if (ids == null) {
            throw new BadRequestException("未找到留言id");
        }
        for (int id : ids) {
            Optional<Msg> res = msgRepository.findById(id);
            if (!res.isPresent()) {
                throw new BadRequestException("未找到该留言id");
            }
            Msg msg = res.get();
            msg.setAuditStatus("审核通过");
            msgRepository.save(msg);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(Msg resources) {
        Msg msg = msgRepository.findById(resources.getId()).orElseGet(Msg::new);
        ValidationUtil.isNull(msg.getId(), "Msg", "id", resources.getId());
        msg.copy(resources);
        msgRepository.save(msg);
    }

    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            //msgRepository.deleteById(id);
            Optional<Msg> res = msgRepository.findById(id);
            if (res.isPresent()) {
                Msg msg = res.get();
                msg.setIsDelete(1);
                msgRepository.save(msg);
            }
        }
    }

    public void download(List<MsgDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MsgDto msg : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("类型 字典 msg_type", msg.getType());
            map.put("关联id", msg.getGlId());
            map.put("审核状态  字典 qy_audit_status", msg.getAuditStatus());
            map.put("留言用户id", msg.getUserId());
            map.put("具体留言内容", msg.getContext());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}